home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1991 / 01 / speedo1.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  14KB  |  506 lines

  1. /**********************************************
  2.  
  3.    Program Name:   FONTDEMO.C
  4.    Module Name:    SPEEDO1.C
  5.    Author:         Ron Fosner
  6.    Creation Date:  March-90
  7.  
  8.    Copyright Ron Fosner, (c) 1990
  9.  
  10.    Description:
  11.      An program to demonstrate dynamic font generation.
  12.       This file contains the library specific calls & code.
  13.  
  14. ***********************************************/
  15.  
  16. /* use function prototypes in speedo h file */
  17. #define PROTOS_AVAIL 1
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <graph.h>
  22. #include "speedo.h"    /* include the speedo header */
  23. #include "local.h"     /* local definitions for this program */
  24.  
  25. /**********************************************/
  26. /* static function prototyes                  */
  27.  
  28. static ufix8 read_1b(ufix8* ptr);
  29. static fix31 read_4b(ufix8* ptr);
  30. static fix15 read_2b(ufix8* ptr);
  31. static void place_char( char c );
  32.  
  33. /**********************************************/
  34. /* external data used by the output routines */
  35.  
  36. extern POINT points_per_pixel;
  37. extern int  PixelsperInch_x,PixelsperInch_y,
  38.       Point_x,Point_y,
  39.       Value_xy,Value_yx;
  40. extern short color0, color1, color2;
  41.  
  42. /**********************************************/
  43. /* static data used by the input routines */
  44.  
  45. static ufix16  ORUs_per_em;
  46. static  ufix8*  font_buffer = NULL; /* Pointer to allocated Font buffer */
  47. static  ufix8*  char_buffer = NULL; /* Pointer to allocate Character buffer */
  48. static  buff_t font;               /* Buffer descriptor for font data */
  49. static  ufix16 minimum_char_buffer_size;/* minimum character buffer size */
  50. static ufix32  minimum_buffer_size;/* minimum font buffer size to allocate */
  51. static int   first_char_index;   /* Index of first character in font */
  52. static FILE * fp = NULL;          /* the font file pointer */
  53.  
  54. /* static data used by the output routines */
  55.  
  56. /* offsets of where to start the first character */
  57. static POINT  char_origin, char_shift, line_origin;
  58.  
  59.  
  60. /**********************************************/
  61. /*
  62.     origin: this routine resets the local origin values
  63.        to their initial values
  64. */
  65.  
  66. void origin()
  67. {
  68.      char_origin.x = char_origin.y = 0;
  69.  
  70.      line_origin.x = Point_x*points_per_pixel.x;
  71.      line_origin.y = Point_y*points_per_pixel.y;
  72. }
  73.  
  74. /**********************************************/
  75. /*
  76.     newline: this routine resets the local horizontal origin
  77.        to the next line (move it down by the point size )
  78.        resets the vertical to its original value
  79.        - and draws in a baseline
  80. */
  81.  
  82. void newline( void )
  83. {
  84.      char_origin.x = char_origin.y = 0;
  85.  
  86.      line_origin.x  = Point_x*points_per_pixel.x;
  87.      line_origin.y += Point_y*points_per_pixel.y;
  88.  
  89.      _setcolor( color1 );
  90.      _moveto(video.x_pixels-1, line_origin.y);
  91.      _lineto(line_origin.x, line_origin.y);
  92.      _setcolor( color0 );
  93. }
  94.  
  95. /**********************************************/
  96. /*
  97.     place_char: this routine take an ASCII char value,
  98.        converts it to Bitstream's character index,
  99.        tells the routine to make the char bitmap (which
  100.        causes the character to be displayed) then returns.
  101. */
  102.  
  103. static void place_char( char c )
  104. {
  105.   ufix16 char_index;    /* Index of character to be generated */
  106.   ufix16 char_id;       /* Character ID */
  107.  
  108.      if ( c == '\n' )
  109.       {
  110.       newline();
  111.       return;
  112.       }
  113.  
  114.      /* Force Bitstream index to ascii */
  115.   char_index = c + first_char_index - 32;
  116.  
  117.   char_id = sp_get_char_id((ufix16)char_index);
  118.  
  119.      /* make the bitmap */
  120.      if ( 0 != char_id )
  121.       sp_make_char(char_index);
  122. }
  123.  
  124.  
  125. /**********************************************/
  126. /*
  127.     place_text: this routine takes a string and
  128.        calls place_char for each character.
  129. */
  130.  
  131.  
  132. void place_text( char  * string )
  133. {
  134.      while ( *string )
  135.       place_char( *string++ );
  136. }
  137.  
  138.  
  139. /**********************************************/
  140. /*
  141.     start_speedo:
  142.        The call to start up the library routines,
  143.        set the parameters to generate the bitmaps we want.
  144.        The argument is the location and name of the speedo file
  145.        for the typeface we want to use.
  146.        If an error occurs, a char pointer is returned pointing
  147.        to the error message, else NULL is returned.
  148. */
  149.  
  150. char * start_speedo( char * pathname )
  151. {
  152.      int      bytes_read;
  153.      specs_t  specs; /* Bundle of character generation specs  */
  154.      ufix8    header_buffer[500]; /* Font buffer */
  155.      char     text_string[128];  /* display info */
  156.  
  157.      /* Load Speedo outline file */
  158.  
  159.      fp = fopen (pathname, "rb");
  160.  
  161.      if ( NULL == fp )
  162.       return("****** Error: Cannot open the font file");
  163.  
  164.      /* read in header info */
  165.  
  166.      bytes_read =
  167.       fread( header_buffer, sizeof(ufix8), sizeof(header_buffer), fp );
  168.  
  169.      if ( 0 == bytes_read )
  170.     {
  171.       fclose(fp);
  172.       fp = NULL;
  173.       return("****** Error on reading font file header");
  174.     }
  175.  
  176.       /* make it in terms of ORU's */
  177.  
  178.      ORUs_per_em = (ufix16)read_2b(header_buffer + FH_ORUPM);
  179.  
  180.      /* read the minumum buffer size for reading in characters */
  181.  
  182.      minimum_buffer_size = (ufix32)read_4b(header_buffer+FH_FBFSZ);
  183.  
  184.      if ( NULL != font_buffer )
  185.       free( font_buffer );
  186.  
  187.      if (NULL == (font_buffer = (ufix8 *)malloc((ufix16)minimum_buffer_size)))
  188.       {
  189.       fclose(fp);
  190.       fp = NULL;
  191.       return("****** Error: Unable to allocate memory for font buffer");
  192.       }
  193.  
  194.      /* now load the fonts */
  195.  
  196.      fseek( fp, (ufix32)0, 0);
  197.  
  198.      if (0 == (bytes_read = fread((ufix8 *)font_buffer,
  199.            sizeof(ufix8), (ufix16)minimum_buffer_size, fp) ) )
  200.        {
  201.      fclose(fp);
  202.       fp = NULL;
  203.       return("****** Error on reading the fonts from the file");
  204.        }
  205.  
  206.      /* now allocate minimum character buffer */
  207.  
  208.      minimum_char_buffer_size = read_2b(font_buffer+FH_CBFSZ);
  209.  
  210.      if ( NULL != char_buffer )
  211.       free( char_buffer );
  212.  
  213.      if (NULL == (char_buffer = (ufix8*)malloc(minimum_char_buffer_size)))
  214.       {
  215.        fclose(fp);
  216.       fp = NULL;
  217.       return("****** Error: Unable to allocate memory for character buffer");
  218.       }
  219.  
  220.      font.org         = font_buffer;
  221.      font.no_bytes    = bytes_read;
  222.      first_char_index = read_2b(font_buffer + FH_FCHRF);
  223.  
  224.      /* Initialization */
  225.  
  226.      sp_reset(); /* Reset Speedo character generator */
  227.  
  228.      /* Set specifications for character to be generated */
  229.  
  230.      specs.pfont    = &font;        /* Pointer to Speedo outline structure */
  231.      specs.xoffset  = 0L << 16;     /* Position of X origin */
  232.      specs.yoffset  = 0L << 16;     /* Position of Y origin */
  233.      specs.flags    = MODE_0;       /* Mode flags */
  234.      specs.out_info = NULL;
  235.  
  236.  
  237.      /* the values are multiplied by 65,536 (shifted left 16)
  238.       to conform to the internal representation used by Speedo.
  239.       This retains high accuracy while using integer math only */
  240.  
  241.           /* Calculate X */
  242.      specs.xxmult = ( (unsigned long)(Point_x*PixelsperInch_x)<< 16 )
  243.       /(unsigned long)72;
  244.  
  245.           /* Calculate Y */
  246.      specs.yymult = ( (unsigned long)(Point_y*PixelsperInch_y) <<16 )
  247.       /(unsigned long)72;
  248.  
  249.            /* Coeff of Y to calculate X pixels */
  250.      specs.xymult = (unsigned long)(Value_xy)<< 16;
  251.  
  252.            /* Coeff of X to calculate Y pixels */
  253.      specs.yxmult = (unsigned long)(Value_yx)<< 16;
  254.  
  255.      /* OK, now call into the library with these settings */
  256.  
  257.      if ( !sp_set_specs(&specs) )
  258.       {
  259.        fclose(fp);
  260.       fp = NULL;
  261.     return("****** Cannot set requested character specs");
  262.       }
  263.  
  264.      /* all went well */
  265.  
  266.      /* print out some info telling what the values
  267.      of the parameters are on the top of the screen */
  268.  
  269.      _settextposition(1,1);
  270.      _settextcolor(6);
  271.      sprintf( text_string, "%s  X point = %d  Y Point = %d  xyvalue = %u  yxvalue = %u ",
  272.       (char *)(header_buffer + FH_FNTNM),Point_x, Point_y,Value_xy,Value_yx);
  273.      _outtext( text_string );
  274.  
  275.      return( NULL );
  276.  
  277. }
  278.  
  279.  
  280. /*** Now begins the routines required to use Speedo ***/
  281.  
  282.  
  283. /**********************************************/
  284. /*
  285.     sp_set_bitmap_bits:
  286.        Three arguments, the horizontal raster line, followed
  287.        by the beginning and ending vertical positions for
  288.        a line to be drawn. This is the  routine that actually draws
  289.        the character.
  290. */
  291.  
  292.  
  293. void sp_set_bitmap_bits( fix15 y, fix15 x1, fix15 x2 )
  294. {
  295.  
  296.      POINT start, stop;
  297.  
  298.      /* convert from speedo bits to screen pixels */
  299.  
  300.      start.x = line_origin.x + char_origin.x + x1;
  301.      stop.x  = line_origin.x + char_origin.x + x2 - 1;
  302.  
  303.      start.y = stop.y = line_origin.y - char_origin.y + y;
  304.  
  305.      _moveto( start.x, start.y );
  306.      _lineto( stop.x, stop.y );
  307.  
  308. }
  309.  
  310.  
  311. /**********************************************/
  312. /*
  313.     sp_open_bitmap:
  314.        The first call to start a character, we save the set_widths
  315.        so we can move the current cahr position when we are done,
  316.        The origins are where we initially offset the char from the
  317.        starting location (some leading space), and the size parameters
  318.        are the dimensions of the bitmap, of which we only use the
  319.        vertical since our origin system is in the upper left corner.
  320. */
  321.  
  322. void sp_open_bitmap( fix31 x_set_width, fix31 y_set_width,
  323.              fix31 x_org, fix31 y_org, fix15 x_size, fix15 y_size )
  324. {
  325.  
  326.      /* save the x and y set widths so we know where
  327.      the next char is to start */
  328.  
  329.      /* use integer math to retain accuracy */
  330.  
  331.      char_shift.x = (int)( (x_set_width+32768)/(65536) );
  332.      char_shift.y = (int)( (y_set_width+32768)/(65536) );
  333.  
  334.      /* add in the leading spacing for this bitmap */
  335.  
  336.      char_origin.x += (int)( (x_org+(fix31)32768) / (fix31)65536 );
  337.  
  338.      char_origin.y  = y_size + (int)( (y_org+(fix31)32768) / (fix31)65536 );
  339.  
  340. }
  341.  
  342.  
  343. /**********************************************/
  344.  
  345. /*
  346.     sp_close_bitmap:
  347.        The last call for a character, we use the set_widths
  348.        we saved to move the current point to the end of the
  349.        character we just drew, in preparation for the next one.
  350. */
  351. void sp_close_bitmap( void )
  352. {
  353.      /* we are done with this character, so
  354.        update the current char origin */
  355.  
  356.      char_origin.x += char_shift.x;
  357.      char_origin.y += char_shift.y;
  358.  
  359. }
  360.  
  361.  
  362. /**********************************************/
  363. /*
  364.     sp_report_error:
  365.        The library calls this when an error occurs.
  366. */
  367.  
  368. void sp_report_error( fix15 error_number )
  369. {
  370.      /*
  371.       the following are SPEEDO errors that
  372.       can be generated during calls to various
  373.       library routines.
  374.      */
  375.  
  376.      static char *message[] =
  377.       {
  378.       "Insufficient font data loaded",
  379.       "?",
  380.       "Transformation matrix out of range",
  381.       "Font format error",
  382.       "Requested specs not compatible with selected output module",
  383.       "?",
  384.       "Intelligent scaling requested but not supported",
  385.       "Unsupported output module requested",
  386.       "Extended font loaded but only compact font supported",
  387.       "Font specs not set prior to use",
  388.       "?",
  389.       "Character not available",
  390.       "Track kerning request rejected due to absence of required data in font",
  391.       "Pair kerning request rejected due to absence of required data in font"
  392.       };
  393.  
  394.      /* reset video mode */
  395.      RESET_VIDEO_MODE;
  396.  
  397.      /* display the error message */
  398.      printf( message[error_number-1] );
  399.      printf("\n");
  400.  
  401.      exit(2); /* quit the program */
  402.  
  403. }
  404.  
  405.  
  406. /**********************************************/
  407. /*
  408.     sp_load_char_data:
  409.       This routine is to provide dynamic character loading
  410.       so that memory is conserved. It is not necessary
  411.       to use dynamic loading if you don't mind reading in the
  412.       enire font file at once, but most people will be interested
  413.       in trading speed for using less memory.
  414.       All it does is read in the requested number of bytes (no_bytes)
  415.       from the file at an offset (file_offset) into the location
  416.       in the character buffer (cb_offset).
  417.       It returns a pointer to the buffer.
  418. */
  419.  
  420. buff_t *sp_load_char_data( fix31 file_offset,
  421.          fix15 no_bytes, fix15 cb_offset)
  422.  
  423.  
  424. {
  425.   /* Buffer descriptor for character data must be static
  426.      since we are passing back a pointer to it */
  427.  
  428.      static  buff_t char_data;
  429.      int     bytes_read;
  430.  
  431.      if ( NULL == fp )
  432.     {
  433.        RESET_VIDEO_MODE;
  434.     printf( "SP_LOAD_CHAR_DATA ERROR file never opened");
  435.     exit(1);
  436.     }
  437.  
  438.      if ( 0 != fseek( fp, (long)file_offset, (int)0 ) )
  439.     {
  440.        RESET_VIDEO_MODE;
  441.     printf( "SP_LOAD_CHAR_DATA ERROR in seeking character");
  442.     fclose( fp );
  443.       fp = NULL;
  444.     exit( 1 );
  445.     }
  446.  
  447.      if ( (no_bytes + cb_offset) > minimum_char_buffer_size )
  448.     {
  449.        RESET_VIDEO_MODE;
  450.     printf( "SP_LOAD_CHAR_DATA ERROR Character buffer overflow");
  451.     fclose( fp );
  452.       fp = NULL;
  453.     exit( 1 );
  454.     }
  455.  
  456.      bytes_read = fread( (char_buffer + cb_offset), sizeof(ufix8), no_bytes, fp);
  457.      if ( bytes_read != no_bytes )
  458.     {
  459.        RESET_VIDEO_MODE;
  460.     printf( "SP_LOAD_CHAR_DATA ERROR on reading character data");
  461.     fclose( fp );
  462.       fp = NULL;
  463.     exit( 1 );
  464.     }
  465.  
  466.      char_data.org = (ufix8 FONTFAR *)char_buffer + cb_offset;
  467.      char_data.no_bytes = no_bytes;
  468.  
  469.      return( &char_data );
  470.  
  471. }
  472.  
  473. /**********************************************/
  474. /*
  475.    functions patterned from some in Bitstream's nsample.c
  476.    program that read one, two, and four bytes
  477.    from the font buffer
  478. */
  479.  
  480. static ufix8 read_1b( ufix8 *pointer ) /* 1 byte */
  481. {
  482.    return *pointer;
  483. }
  484.  
  485. static fix15 read_2b( ufix8 *pointer ) /* 2 bytes */
  486. {
  487.      fix31 temp;
  488.  
  489.      temp = *pointer++;
  490.      temp = (temp << 8) + *(pointer);
  491.      return( (fix15)temp );
  492. }
  493.  
  494. static fix31 read_4b( ufix8 *pointer ) /* 4 bytes */
  495. {
  496.      fix31 temp;
  497.  
  498.      temp = *pointer++;
  499.      temp = (temp << 8) + *(pointer++);
  500.      temp = (temp << 8) + *(pointer++);
  501.      temp = (temp << 8) + *(pointer  );
  502.      return( temp );
  503. }
  504.  
  505.  
  506.